package com.redpack.quick.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.redpack.quick.consts.Constants;
import com.redpack.quick.datasource.dao.CashHistoryDao;
import com.redpack.quick.datasource.dao.UserInfoDao;
import com.redpack.quick.datasource.entity.CashHistoryEntity;
import com.redpack.quick.datasource.entity.UserInfoEntity;
import com.redpack.quick.service.IUserInfo;
import com.redpack.quick.utils.DateUtils;
import com.redpack.quick.utils.Md5Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by shuttle on 4/3/18.
 */
@Service("userInfo")
public class UserInfoImpl implements IUserInfo {

    @Autowired
    UserInfoDao userInfoDao;

    @Autowired
    CashHistoryDao cashHistoryDao;

    @Override
    public UserInfoEntity save(UserInfoEntity entity, String token) {
        if (entity.getId() == 0) {
            entity.setCreatetime(DateUtils.getCurrentTimeStamp());
        } else {
            UserInfoEntity originInfo = userInfoDao.findOne(entity.getId());
            if (Md5Utils.stringMD5(originInfo.getOpenId()).equals(token)) {
                originInfo.setMobile(entity.getMobile());
                originInfo.setAlipay(entity.getAlipay());
                originInfo.setName(entity.getName());
                originInfo.setWxNumber(entity.getWxNumber());
                originInfo.setIdCard(entity.getIdCard());
                originInfo.setUpdatetime(DateUtils.getCurrentTimeStamp());
                return userInfoDao.save(originInfo);
            }
            return null;
        }
        entity.setUpdatetime(DateUtils.getCurrentTimeStamp());
        return userInfoDao.save(entity);
    }

    @Override
    public UserInfoEntity findByUserId(long id, String token) {
        UserInfoEntity entity = userInfoDao.findOne(id);
        if (Md5Utils.stringMD5(entity.getOpenId()).equals(token)) {
            entity.setOpenId("");
            entity.setSessionKey("");
            return entity;
        }
        return null;
    }

    @Override
    public UserInfoEntity findByAppId(String openId) {
        UserInfoEntity entity = userInfoDao.findByOpenId(openId);
        entity.setOpenId("");
        entity.setSessionKey("");
        return entity;
    }

    @Override
    public Map<String, String> login(String code) {
        String appId = Constants.APP_ID;
        String secret = Constants.SECRET;
        String url = Constants.WX_LOGIN_URL + "?appid=" + appId + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
        JSONObject object = getSessionKeyOropenid(code);
        UserInfoEntity userInfoEntity = findByAppId(object.getString("openid"));
        Map<String, String> mapResult = new HashMap<>();
        mapResult.put("openId", Md5Utils.stringMD5(object.getString("openid")));
        if (userInfoEntity == null) {
            UserInfoEntity entity = new UserInfoEntity();
            entity.setOpenId(object.getString("openid"));
            entity.setSessionKey(object.getString("session_key"));
            entity = userInfoDao.save(entity);
            mapResult.put("userId", entity.getId() + "");
        } else {
            mapResult.put("userId", userInfoEntity.getId() + "");
        }
        return mapResult;
    }

    public int getMoney(String uid, String token, BigDecimal quota) {
        UserInfoEntity user = userInfoDao.findOne(Long.parseLong(uid));
        if (quota.compareTo(user.getAccount()) == 1) {
            return 2;
        }
        if (Md5Utils.stringMD5(user.getOpenId()).equals(token)) {
            if(cashHistoryDao.findByUidAndStatus(uid, 0).size() == 0 ) {
                CashHistoryEntity entity = new CashHistoryEntity();
                entity.setUid(uid);
                entity.setOutCharge(quota);
                entity.setStatus(0);
                cashHistoryDao.save(entity);
                user.setAccount(user.getAccount().subtract(quota));
                userInfoDao.save(user);
                return 1;
            }
        }
        return 0;
    }

    public boolean getCashHistory(String uid, String token){
        if(cashHistoryDao.findByUidAndStatus(uid, 0).size() == 0 ) {
            return false;
        }
        return true;
    }

    public static JSONObject getSessionKeyOropenid(String code) {
        //微信端登录code值
        String wxCode = code;
        String requestUrl = Constants.WX_LOGIN_URL;  //请求地址 https://api.weixin.qq.com/sns/jscode2session
        Map<String, String> requestUrlParam = new HashMap<>();
        requestUrlParam.put("appid", Constants.APP_ID);  //开发者设置中的appId
        requestUrlParam.put("secret", Constants.SECRET); //开发者设置中的appSecret
        requestUrlParam.put("js_code", wxCode); //小程序调用wx.login返回的code
        requestUrlParam.put("grant_type", "authorization_code");    //默认参数

        //发送post请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取openid用户唯一标识
        JSONObject jsonObject = JSON.parseObject(sendPost(requestUrl, requestUrlParam));
        return jsonObject;
    }

    public static String sendPost(String url, Map<String, ?> paramMap) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";

        String param = "";
        Iterator<String> it = paramMap.keySet().iterator();

        while (it.hasNext()) {
            String key = it.next();
            param += key + "=" + paramMap.get(key) + "&";
        }

        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            //Logger.error(e.getMessage(), e);
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
}
